package com.exrobot.module.rbt.controller.admin.order;

import com.exrobot.module.rbt.controller.admin.orderitem.vo.OrderItemPageReqVO;
import com.exrobot.module.rbt.controller.admin.orderitem.vo.OrderItemRespVO;
import com.exrobot.module.rbt.controller.admin.robottask.vo.RobotTaskSaveReqVO;
import com.exrobot.module.rbt.dal.dataobject.canteeninfo.CanteenInfoDO;
import com.exrobot.module.rbt.dal.dataobject.orderitem.OrderItemDO;
import com.exrobot.module.rbt.dal.dataobject.robotinfo.RobotInfoDO;
import com.exrobot.module.rbt.enums.RbtTaskStatusEnum;
import com.exrobot.module.rbt.enums.RbtTaskTypeEnum;
import com.exrobot.module.rbt.framework.util.CommonUtils;
import com.exrobot.module.rbt.service.canteeninfo.CanteenInfoService;
import com.exrobot.module.rbt.service.orderitem.OrderItemService;
import com.exrobot.module.rbt.service.robotScheduler.RobotSchedulerService;
import com.exrobot.module.rbt.service.robottask.RobotTaskService;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;

import com.exrobot.framework.common.pojo.PageParam;
import com.exrobot.framework.common.pojo.PageResult;
import com.exrobot.framework.common.pojo.CommonResult;
import com.exrobot.framework.common.util.object.BeanUtils;
import static com.exrobot.framework.common.pojo.CommonResult.success;

import com.exrobot.framework.excel.core.util.ExcelUtils;

import com.exrobot.framework.apilog.core.annotation.ApiAccessLog;
import static com.exrobot.framework.apilog.core.enums.OperateTypeEnum.*;

import com.exrobot.module.rbt.controller.admin.order.vo.*;
import com.exrobot.module.rbt.dal.dataobject.order.OrderDO;
import com.exrobot.module.rbt.service.order.OrderService;

@Tag(name = "管理后台 - 食堂信息")
@RestController
@RequestMapping("/rbt/order")
@Validated
public class OrderController {

    @Resource
    private OrderService orderService;

    @Resource
    private OrderItemService orderItemService;

    @Resource
    private CanteenInfoService canteenInfoService;

    @Resource
    private RobotSchedulerService robotSchedulerService;

    @Resource
    private RobotTaskService taskService;

    @PostMapping("/create")
    @Operation(summary = "创建食堂信息")
    @PreAuthorize("@ss.hasPermission('rbt:order:create')")
    public CommonResult<OrderDO> createOrder(@Valid @RequestBody OrderSaveReqVO createReqVO) {
        return success(orderService.createOrder(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新食堂信息")
    @PreAuthorize("@ss.hasPermission('rbt:order:update')")
    public CommonResult<Boolean> updateOrder(@Valid @RequestBody OrderSaveReqVO updateReqVO) {
        OrderItemPageReqVO itemPageReqVO = new OrderItemPageReqVO();
        itemPageReqVO.setOrderSn(updateReqVO.getOrderSn());
        List<OrderItemDO> itemDOS = orderItemService.getOrderItemList(itemPageReqVO);
        if(itemDOS != null && !itemDOS.isEmpty()) {
            RobotInfoDO robotInfoDO = robotSchedulerService.orderMatchRobot(CommonUtils.getFloorByPoint(updateReqVO.getPoint()),itemDOS);
            if(robotInfoDO != null) {
                RobotTaskSaveReqVO createReqVO = new RobotTaskSaveReqVO();
                createReqVO.setRobotSn(robotInfoDO.getSn());
                createReqVO.setTaskType(RbtTaskTypeEnum.DELIVERY.getTypeVal());
                createReqVO.setPoint(updateReqVO.getPoint());
                createReqVO.setStatus(RbtTaskStatusEnum.START.getVal());
                taskService.createRobotTask(createReqVO);
            }
        }
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除食堂信息")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('rbt:order:delete')")
    public CommonResult<Boolean> deleteOrder(@RequestParam("id") Long id) {
        orderService.deleteOrder(id);
        return success(true);
    }

    @DeleteMapping("/delete-list")
    @Parameter(name = "ids", description = "编号", required = true)
    @Operation(summary = "批量删除食堂信息")
                @PreAuthorize("@ss.hasPermission('rbt:order:delete')")
    public CommonResult<Boolean> deleteOrderList(@RequestParam("ids") List<Long> ids) {
        orderService.deleteOrderListByIds(ids);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得食堂信息")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('rbt:order:query')")
    public CommonResult<OrderRespVO> getOrder(@RequestParam("id") Long id) {
        OrderDO order = orderService.getOrder(id);
        return success(BeanUtils.toBean(order, OrderRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得食堂信息分页")
    @PreAuthorize("@ss.hasPermission('rbt:order:query')")
    public CommonResult<PageResult<OrderRespVO>> getOrderPage(@Valid OrderPageReqVO pageReqVO) {
        PageResult<OrderDO> pageResult = orderService.getOrderPage(pageReqVO);
        if (pageResult.getList() == null || pageResult.getList().isEmpty()) {
            return success(new PageResult<>());
        }
        Map<Long,CanteenInfoDO> canteenInfoDOMap = canteenInfoService.getCanteenInfoMap(pageResult.getList().stream().map(OrderDO::getCanteenSn).collect(Collectors.toSet()));
        Map<String, List<OrderItemRespVO>> orderItemMap = orderItemService.getOrderItemListMap(pageResult.getList().stream().map(OrderDO::getOrderSn).collect(Collectors.toSet()));
        return success(BeanUtils.toBean(pageResult, OrderRespVO.class,o->{
            if(orderItemMap.containsKey(o.getOrderSn())) {
                o.setItems(orderItemMap.get(o.getOrderSn()));
            }
            if(canteenInfoDOMap.containsKey(o.getCanteenSn())) {
                o.setCanteenName(canteenInfoDOMap.get(o.getCanteenSn()).getName());
            }
        }));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出食堂信息 Excel")
    @PreAuthorize("@ss.hasPermission('rbt:order:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportOrderExcel(@Valid OrderPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<OrderDO> list = orderService.getOrderPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "食堂信息.xls", "数据", OrderRespVO.class,
                        BeanUtils.toBean(list, OrderRespVO.class));
    }

}